import React, { PureComponent } from 'react';
import { connect } from 'dva';
import myStyle from './index.less';
import { ExclamationCircleOutlined } from '@ant-design/icons';
import { Form } from '@ant-design/compatible';
import '@ant-design/compatible/assets/index.css';
import { Popconfirm, message } from 'antd';
import { TableC, SelectC, ModalC, PrimaryC, PrimaryGhostC, InputNumberC, FirstHeaderC, TreeSelectC } from '../../../../comps';
import { fixedNum, getProductName, isRepeat } from '../../../../utils/utils';
import _ from 'lodash';
import uuid from 'es6-uuid';
import dictData from './dictConfig';
import { number } from 'prop-types';

@Form.create()
class SplitTableC extends PureComponent {
  state = {
    ratio: '0.00%', // 已分配比例
    assignAmount: 0, // 已分配数量
    dataSource: [], // 表格数据源
    currentRow: undefined, // 正在编辑的行 之前的数据
    editFlag: false, // 编辑状态
    selectedRowKeys: [], // 已选中项
  };

  componentDidMount() {
    this.props.onRef(this);
    this.setState({
      dataSource: _.cloneDeep(this.props.dataSource),
      ratio: this.props.isDetail ? '100.00%' : '0.00%', // 已分配比例
      assignAmount: this.props.isDetail ? this.props.tradeInfo.amount : 0, // 已分配数量
    });
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    if (JSON.stringify(this.props.dataSource) != JSON.stringify(nextProps.dataSource)) {
      this.saveDataSource(_.cloneDeep(nextProps.dataSource))
    }
  }

  // 用户点击确定
  submit = () => {
    const { dataSource, ratio, assignFee } = this.state;
    const { tradeInfo } = this.props;
    if (!dataSource.length) {
      message.warning('请先新增数据');
      return;
    }
    const arrEdit = dataSource.filter((item) => item.isEdit);
    const arrTradeNum = dataSource.filter((item) => item.tradeNum == 0);
    if (arrEdit.length) {
      message.warning('请先保存正在编辑的数据');
      return;
    }
    if (arrTradeNum.length) {
      message.warning('请删除交易数量为0的数据');
      return;
    }
    if (ratio !== '100.00%') {
      message.warning('拆分的交易数量总和需与交易总量数目一致');
      return;
    }
    if (tradeInfo.fee && assignFee != tradeInfo.fee) {
      // 有尾差，最后一个组合中加入尾差，即表格中的费用之和等于交易信息的费用
      dataSource[dataSource.length - 1].fee = dataSource[dataSource.length - 1].fee + (tradeInfo.fee - assignFee);
      this.setState({
        assignFee: tradeInfo.fee,
      });
      this.saveDataSource(dataSource)
      this.props.feeChange(tradeInfo.fee); // 抛出已分配费用
    }
    return dataSource;
  };

  // 产品组合变更
  onChangeProduct = (e, option, record) => {
    const { dataSource } = this.state;
    dataSource.map((item) => {
      // 对应的其他属性
      if (item.key == record.key) {
        item.productId = e;
        if (option) item.name = option[0];
      }
      this.props.fundList &&
        this.props.fundList.map((x) => {
          // 新增的条目 可用金额不变
          if (x.nodeId == item.productId) {
            item.t0 = x.t0;
            item.t1 = x.t1;
          }
        });
      this.props.holdList &&
        this.props.holdList.map((x) => {
          // 新增的条目 持仓数量
          if (x.fundId == item.productId) {
            item.available = x.available;
            item.hold = x.hold;
          }
        });
    });

    // if(e)this.queryInfo(e);
    this.saveDataSource(dataSource)
  };

  // 交易数量变更
  onChangeTradeNum = (e, record) => {
    const { dataSource } = this.state;
    const { tradeInfo } = this.props;
    dataSource.map((item) => {
      if (item.key == record.key) {
        if (typeof e !== 'number') return;
        item.tradeNum = e;
        // 计算交易金额
        if (tradeInfo.direction != 4) item.tradePrice = tradeInfo[dictData.priceToType[tradeInfo.orderType]] * (e ? e : 0);
        // 计算费用
        item.fee = this.calcFee(e);
      }
    });
    this.calcAssign(); // 计算已分配费用 比例 数量
    this.saveDataSource(dataSource)
  };

  // 计算已分配费用 比例 数量
  calcAssign = () => {
    const { dataSource } = this.state;
    const { tradeInfo } = this.props;
    // 计算已分配费用 比例 数量
    let tradeNumSum = 0;
      let feeNumSum = 0;
    dataSource.map((item) => {
      tradeNumSum += item.tradeNum !== undefined && item.tradeNum !== null ? item.tradeNum : 0;
      feeNumSum += item.fee !== undefined && item.fee !== null ? item.fee : 0;
    });
    if (tradeInfo.fee) this.props.feeChange(feeNumSum.toFixed(2));
    this.setState({
      assignAmount: tradeNumSum,
      assignFee: tradeInfo.fee ? feeNumSum.toFixed(2) : undefined,
      ratio: `${parseFloat((tradeNumSum / tradeInfo.amount) * 100).toFixed(2)  }%`,
    });
  };

  // 费用计算
  calcFee = (tradeNum) => {
    // 更改【交易数量】，【费用（表格中组合费用）】= 交易数量/交易总量*费用（交易信息中的总费用），更改交易信息中费用分配情况；
    // 若有尾差，最后一个组合中加入尾差，即表格中的费用之和等于交易信息的费用；
    const { tradeInfo } = this.props;
    if (!tradeInfo.fee) return null;
    const num = (tradeNum / tradeInfo.amount) * tradeInfo.fee;
    return Number(num.toFixed(2));
  };

  // 拆分表格
  renderTable = () => {
    const { loading, settlement } = this.props;
    const width = 150;
    const columns = [
      {
        title: '产品组合',
        key: 'productId',
        width: 196,
        fixed: 'left',
        render: (text, record, index) => {
          if (!record.isEdit) {
            return (
              <span title={record.name} style={{ display: 'inline-block', width: '180px', overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }}>
                {record.name === null || record.name === undefined ? '--' : record.name}
              </span>
            );
          }
          if (record.isEdit) {
            return (
              <TreeSelectC
                form={this.props.form} // form对象
                dataIndex={'productId'} // Form识别的Item ID
                dataSource={this.props.portfolioTree}
                onChange={(e, option) => this.onChangeProduct(e, option, record)}
                initialValue={record.productId}
                treeDefaultExpandAll={true}
                positionBody={true}
              />
            );
          }
        },
      },
      { title: 'T+0可用', key: 't0', type: 'money', width },
      { title: 'T+1可用', key: 't1', type: 'money', width },
      { title: '持仓数量', key: 'hold', type: 'number', width },
      { title: '可用数量', key: 'available', type: 'number', width },
      {
        title: '交易数量',
        key: 'tradeNum',
        align: 'right',
        width,
        render: (text, record, index) => {
          if (!record.isEdit) {
            return <span>{text === undefined ? '--' : fixedNum(text, 0)}</span>;
          }
          if (record.isEdit) {
            return (
              <InputNumberC
                form={this.props.form} // form对象
                dataIndex={'tradeNum'}
                initialValue={record.tradeNum}
                onChange={(e) => {
                  this.onChangeTradeNum(e, record);
                }}
                min={0}
                splitStyle={true}
                // unit={"股"}
              />
            );
          }
        },
      },
      { title: '交易金额', key: 'tradePrice', type: 'money', width },
      { title: '费用', key: 'fee', type: 'number', toFixed: 2, width },
    ];
    if (settlement) {
      columns.push({ title: '交收状态', key: 'instructionStatus' });
    }
    if (!this.props.isDetail) {
      if (columns && columns[columns.length - 1].key != 'operate') {
        columns.push({
          title: '操作',
          dataIndex: 'operate',
          key: 'operate',
          type: 'operate',
          fixed: 'right',
          width: 100,
          operates: [
            {
              title: '保存',
              onClick: (record, index) => this.saveRow(record),
              rules: {
                hide: { relation: 'and', items: [{ key: 'isEdit', value: [false], relation: ['='] }] },
              },
            },
            {
              title: '取消',
              onClick: (record, index) => this.cancelRow(record.key),
              rules: {
                hide: { relation: 'and', items: [{ key: 'isEdit', value: [false], relation: ['='] }] },
              },
            },
            {
              title: '编辑',
              onClick: (record, index) => this.editRow(record),
              rules: {
                hide: { relation: 'and', items: [{ key: 'isEdit', value: [true], relation: ['='] }] },
              },
            },
            {
              title: '删除',
              onClick: (record, index) => this.deleteRow(record.key),
              rules: {
                hide: { relation: 'and', items: [{ key: 'isEdit', value: [true], relation: ['='] }] },
              },
            },
          ],
        });
      }
    }
    const rowSelection = {
      onChange: (selectedRowKeys) => {
        this.setState({
          selectedRowKeys,
        });
      },
    };
    let sum = 0;
    columns.map((item) => {
      sum += (item.width ? item.width : 0);
    });
    const num = settlement ? 130 : 60;
    return (
      <TableC
        columns={columns}
        dataSource={this.state.dataSource}
        scroll={{ x: sum + num, y: window.innerHeight - 500 < 100 ? 100 : window.innerHeight - 500 }}
        loading={this.props.loadingStatus == true || loading.effects['orderSplitM/querySplitTableList1'] == true}
        rowSelection={this.props.isDetail ? undefined : rowSelection}
        hidePage={true}
        rowKey='key'
      />
    );
  };

  // 编辑行
  editRow = (record) => {
    const { dataSource, editFlag } = this.state;
    if (editFlag) {
      message.warning('每次只能编辑一条数据！');
      return;
    }
    this.setState({ currentRow: JSON.parse(JSON.stringify(record)), editFlag: true });
    dataSource.map((item) => {
      if (item.key == record.key) {
        item.isEdit = true;
      }
    });
    this.saveDataSource(dataSource)
  };

  // 取消编辑行 保留原数据
  cancelRow = (key) => {
    const { dataSource, currentRow } = this.state;
    if (!currentRow) {
      const arr = dataSource.filter((item) => item.isEdit != true);
      this.setState(
        {
          dataSource:  JSON.parse(JSON.stringify(arr)),
          editFlag: false,
        },
        () => {
          this.calcAssign(); // 重新计算
        },
      );

      return;
    }
    dataSource.map((item) => {
      if (item.key == key) {
        for (const key in item) {
          item[key] = currentRow[key];
        }
      }
    });
    this.setState(
      {
        dataSource:JSON.parse(JSON.stringify(dataSource)),
        currentRow: undefined,
        editFlag: false,
      },
      () => {
        this.calcAssign(); // 重新计算
      },
    );

  };

  // 删除行
  deleteRow = (key) => {
    const { dataSource, currentRow } = this.state;
    const data = dataSource.filter((item) => item.key != key);
    const arr = data.filter((item) => item.isEdit);
    this.setState(
      {
        dataSource:JSON.parse(JSON.stringify(arr)),
        currentRow: arr.length ? currentRow : undefined, // 注意编辑状态的影响
        editFlag: !!arr.length,
      },
      () => {
        this.calcAssign(); // 重新计算
      },
    );
  };

  addNew = () => {
    const { dataSource } = this.state;
    const obj = {
      tradeNum: 0,
      tradePrice: 0,
      isEdit: true,
      key: uuid(32),
    };
    dataSource.unshift(obj);

    this.setState({
      dataSource: JSON.parse(JSON.stringify(dataSource)),
      editFlag: true,
    });
  };

  // 批量删除
  delBatch = () => {
    const { dataSource, selectedRowKeys, currentRow } = this.state;
    for (let i = 0; i < selectedRowKeys.length; i++) {
      for (let j = 0; j < dataSource.length; j++) {
        if (selectedRowKeys[i] == dataSource[j].key) {
          dataSource.splice(j, 1);
        }
      }
    }
    const arr = dataSource.filter((item) => item.isEdit == true);
    this.setState(
      {
        dataSource:JSON.parse(JSON.stringify(arr)),
        currentRow: arr.length ? currentRow : undefined, // 注意编辑状态的影响
        editFlag: !!arr.length,
        selectedRowKeys: [],
      },
      () => {
        this.calcAssign(); // 重新计算
      },
    );
  };

  // 保存行
  saveRow = (record) => {
    const { dataSource } = this.state;
    const { tradeInfo } = this.props;
    if (!record.productId) {
      message.warning('请选择产品组合');
      return;
    }
    // 校验是否有重复产品组合id
    const arr = dataSource.map((item) => item.productId);
    if (isRepeat(arr)) {
      message.warning('该行的产品组合与其他行重复');
      return;
    }
    // 根据不同的类型 交易方向 进行验资 验券
    /*
            债券交易方向支持：买入、卖出和债回收，其中，买入时要验资，卖出和债回收要验券。
            验资：【交易金额】与【T+0可用】或【T+1可用】对比（看清算速度）
            验券：若是卖出，【交易数量】与【可用数量】对比，若是债回售，【交易数量】与【持仓数量】对比。
        */
    /**
         * 非标、理财直融交易方向支持：买入、卖出，其中，买入时要验资，卖出要验券。
             验资：【交易金额】与【T+0可用】对比
             验券：【交易数量】与【可用数量】对比
         */
    if (tradeInfo.amount < record.tradeNum) {
      // 每行交易数量不可大于交易总量
      message.warning('交易数量不可大于交易总量');
      return;
    }
    if (tradeInfo.orderType == '0') {
      // 债券
      if (tradeInfo.direction == '1') {
        // 买入时要验资
        if (tradeInfo.settlementSpeed == 1) {
          // t0
          if (record.tradePrice > (record.t0 || 0)) {
            message.warning('交易金额不能大于T+0可用');
            return;
          }
        } else if (record.tradePrice > (record.t1 || 0)) {
            message.warning('交易金额不能大于T+1可用');
            return;
          }
      } else {
        // 卖出和债回收要验券。
        if (tradeInfo.direction == '2') {
          // 若是卖出，【交易数量】与【可用数量】对比，
          if (record.tradeNum > (record.available || 0)) {
            message.warning('交易数量不能大于可用数量');
            return;
          }
        } else {
          // 若是债回售，【交易数量】与【持仓数量】对比。
          if (record.tradeNum > (record.hold || 0)) {
            message.warning('交易数量不能大于持仓数量');
            return;
          }
        }
      }
    }
    if (tradeInfo.orderType == '7' || tradeInfo.orderType == '12') {
      // 理财直融、非标、
      if (tradeInfo.direction == '1') {
        // ，买入时要验资，  验资：【交易金额】与【T+0可用】对比
        if (record.tradePrice > (record.t0 || 0)) {
          message.warning('交易金额不能大于T+0可用');
          return;
        }
      } else {
        // 卖出要验券， 验券：【交易数量】与【可用数量】对比
        if (record.tradeNum > (record.available || 0)) {
          message.warning('交易数量不能大于可用数量');
          return;
        }
      }
    }

    // 保存对应数据，去掉编辑状态
    dataSource.map((item) => {
      item.isEdit = false;
    });
    this.setState({
      editFlag: false,
      currentRow: undefined,
    });
    this.saveDataSource(dataSource)
  };

   // 保存dataSource 更新视图 否则数据更新 视图不更新
   saveDataSource=(dava)=>{
    this.setState({
      dataSource:JSON.parse(JSON.stringify(dava))
    })
  }
 

  render() {
    const { tradeInfo } = this.props;
    const { ratio, assignAmount, editFlag, selectedRowKeys } = this.state;
    return (
      <div>
        <div className={myStyle.borderTop}>
          <FirstHeaderC title='手工拆分' />
        </div>
        <div className={myStyle.addBtn}>
          {!this.props.isDetail && (
            <>
              <PrimaryC title='新增' disabled={editFlag == true} onClick={this.addNew} />
              <Popconfirm title={'确定删除？'} icon={<ExclamationCircleOutlined />} onConfirm={this.delBatch}>
                <PrimaryGhostC title='批量删除' disabled={selectedRowKeys.length == false} />
              </Popconfirm>
            </>
          )}
          <div>
            已分配比例:<span>{ratio}</span>
            <span>({`${fixedNum(assignAmount, 0)}/${fixedNum(tradeInfo.amount, 0)}`})</span>
          </div>
        </div>
        {this.renderTable()}
      </div>
    );
  }
}
export default connect(({ tradeHoldM, availableAssetM, loading }) => ({
  tradeHoldM,
  availableAssetM,
  loading,
}))(SplitTableC);
